package com.ybear.ybcomponent.viewhelper;

import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;

public class ViewHelper implements IViewHelper {
    @NonNull
    private final ViewGroup mParent;
    private ViewHelper() { throw new NullPointerException( "not set parent." ); }
    public ViewHelper(@NonNull ViewGroup parent) { mParent = parent; }
    public static ViewHelper create(@NonNull ViewGroup parent) {
        return new ViewHelper( parent );
    }

    /* 通用 ****************************************************************************/

    @Override
    public ViewHelper setBackground(@IdRes int id, Drawable background) {
        View v = findView( id );
        if( v != null ) v.setBackground( background );
        return this;
    }
    @Override
    public ViewHelper setBackgroundColor(@IdRes int id, @ColorInt int color) {
        View v = findView( id );
        if( v != null ) v.setBackgroundColor( color );
        return this;
    }
    @Override
    public ViewHelper setBackgroundResource(@IdRes int id, @DrawableRes int resId) {
        View v = findView( id );
        if( v != null ) v.setBackgroundResource( resId );
        return this;
    }
    @RequiresApi(api = Build.VERSION_CODES.Q)
    @Override
    public ViewHelper setBackgroundTintBlendMode(@IdRes int id, @Nullable BlendMode blendMode) {
        View v = findView( id );
        if( v != null ) v.setBackgroundTintBlendMode( blendMode );
        return this;
    }
    @Override
    public ViewHelper setBackgroundTintList(@IdRes int id, @Nullable ColorStateList tint) {
        View v = findView( id );
        if( v != null ) v.setBackgroundTintList( tint );
        return this;
    }
    @Override
    public ViewHelper setBackgroundTintMode(@IdRes int id, @Nullable PorterDuff.Mode tintMode) {
        View v = findView( id );
        if( v != null ) v.setBackgroundTintMode( tintMode );
        return this;
    }

    @Override
    public ViewHelper setInvisible(@IdRes int id, boolean isVisible) {
        View v = findView( id );
        if( v != null ) v.setVisibility( isVisible ? View.VISIBLE : View.INVISIBLE );
        return this;
    }
    @Override
    public ViewHelper setGone(@IdRes int id, boolean isVisible) {
        View v = findView( id );
        if( v != null ) v.setVisibility( isVisible ? View.VISIBLE : View.GONE );
        return this;
    }

    /* TextView ****************************************************************************/

    @Override
    public ViewHelper setText(@IdRes int id, CharSequence text) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setText( text );
        return this;
    }
    @Override
    public ViewHelper setText(@IdRes int id, String text) {
        setText( id, (CharSequence) text );
        return this;
    }
    @Override
    public ViewHelper setText(@IdRes int id, char[] text, int start, int len) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setText( text, start, len );
        return this;
    }
    @Override
    public ViewHelper setText(@IdRes int id, @StringRes int textResId) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setText( textResId );
        return this;
    }
    @Override
    public ViewHelper setText(@IdRes int id, @StringRes int textResId, TextView.BufferType type) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setText( textResId, type );
        return this;
    }
    @Override
    public ViewHelper setTextSize(@IdRes int id, float size) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setTextSize( size );
        return this;
    }
    @Override
    public ViewHelper setTextSize(@IdRes int id, int unit, float size) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setTextSize( unit, size );
        return this;
    }
    @Override
    public ViewHelper setTextColor(@IdRes int id, @ColorInt int color) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setTextColor( color );
        return this;
    }
    @Override
    public ViewHelper setTypeface(@IdRes int id, @Nullable Typeface tf) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setTypeface( tf );
        return this;
    }
    @Override
    public ViewHelper setTypeface(@IdRes int id, @Nullable Typeface tf, int style) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setTypeface( tf, style );
        return this;
    }
    @Override
    public ViewHelper setHint(@IdRes int id, CharSequence hint) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setHint( hint );
        return this;
    }
    @Override
    public ViewHelper setHint(@IdRes int id, @StringRes int resId) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setHint( resId );
        return this;
    }
    @Override
    public ViewHelper setHintTextColor(@IdRes int id, ColorStateList colors) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setHintTextColor( colors );
        return this;
    }
    @Override
    public ViewHelper setHintTextColor(@IdRes int id, @ColorInt int color) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setHintTextColor( color );
        return this;
    }
    @Override
    public ViewHelper setLinksClickable(@IdRes int id, boolean whether) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setLinksClickable( whether );
        return this;
    }
    @Override
    public ViewHelper setLinkTextColor(@IdRes int id, ColorStateList colors) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setLinkTextColor( colors );
        return this;
    }
    @Override
    public ViewHelper setLinkTextColor(@IdRes int id, @ColorInt int color) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setLinkTextColor( color );
        return this;
    }
    @Override
    public ViewHelper setAutoLinkMask(@IdRes int id, int mask) {
        TextView tv = findTextView( id );
        if( tv != null ) tv.setAutoLinkMask( mask );
        return this;
    }

    /* ImageView ****************************************************************************/

    @Override
    public ViewHelper setImageResource(@IdRes int id, @DrawableRes int resId) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageResource( resId );
        return this;
    }
    @Override
    public ViewHelper setImageAlpha(@IdRes int id, int alpha) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageAlpha( alpha );
        return this;
    }
    @Override
    public ViewHelper setImageBitmap(@IdRes int id, Bitmap bm) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageBitmap( bm );
        return this;
    }
    @Override
    public ViewHelper setImageDrawable(@IdRes int id, @Nullable Drawable drawable) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageDrawable( drawable );
        return this;
    }
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public ViewHelper setImageIcon(@IdRes int id, @Nullable Icon icon) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageIcon( icon );
        return this;
    }
    @Override
    public ViewHelper setImageLevel(@IdRes int id, int level) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageLevel( level );
        return this;
    }
    @Override
    public ViewHelper setImageMatrix(@IdRes int id, Matrix matrix) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageMatrix( matrix );
        return this;
    }
    @Override
    public ViewHelper setImageState(@IdRes int id, int[] state, boolean merge) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageState( state, merge);
        return this;
    }
    @RequiresApi(api = Build.VERSION_CODES.Q)
    @Override
    public ViewHelper setImageTintBlendMode(@IdRes int id, @Nullable BlendMode blendMode) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageTintBlendMode( blendMode );
        return this;
    }
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public ViewHelper setImageTintList(@IdRes int id, @Nullable ColorStateList tint) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageTintList( tint );
        return this;
    }
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public ViewHelper setImageTintMode(@IdRes int id, @Nullable PorterDuff.Mode tintMode) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageTintMode( tintMode );
        return this;
    }
    @Override
    public ViewHelper setImageURI(@IdRes int id, @Nullable Uri uri) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setImageURI( uri );
        return this;
    }
    @Override
    public ViewHelper setScaleType(@IdRes int id, ImageView.ScaleType scaleType) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setScaleType( scaleType );
        return this;
    }
    @Override
    public ViewHelper setScaleMatrix(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.MATRIX );
    }
    @Override
    public ViewHelper setScaleFitXY(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.FIT_XY );
    }
    @Override
    public ViewHelper setScaleFitStart(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.FIT_START );
    }
    @Override
    public ViewHelper setScaleFitCenter(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.FIT_CENTER );
    }
    @Override
    public ViewHelper setScaleFitEnd(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.FIT_END );
    }
    @Override
    public ViewHelper setScaleCenter(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.CENTER );
    }
    @Override
    public ViewHelper setScaleCenterCrop(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.CENTER_CROP );
    }
    @Override
    public ViewHelper setScaleCenterInside(@IdRes int id) {
        return setScaleType( id, ImageView.ScaleType.CENTER_INSIDE );
    }
    @Override
    public ViewHelper setColorFilter(@IdRes int id, int color, PorterDuff.Mode mode) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setColorFilter( color, mode);
        return this;
    }
    @Override
    public ViewHelper setColorFilter(@IdRes int id, int color) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setColorFilter( color );
        return this;
    }
    @Override
    public ViewHelper setColorFilter(@IdRes int id, ColorFilter cf) {
        ImageView iv = findImageView( id );
        if( iv != null ) iv.setColorFilter( cf );
        return this;
    }

    /* ********************************************************************************/

    @Nullable
    @Override
    public final <T extends View> T findView(@IdRes int id) {
        return mParent.findViewById( id );
    }

    private TextView findTextView(@IdRes int id) {
        View view = findView( id );
        if( view instanceof TextView ) {
            return (TextView) view;
        }
        return null;
    }

    private ImageView findImageView(@IdRes int id) {
        View view = findView( id );
        if( view instanceof ImageView ) {
            return (ImageView) view;
        }
        return null;
    }
}
